Package de.yaams.extensions.basemap.tiled.mapeditor.dialogs

Source Code of de.yaams.extensions.basemap.tiled.mapeditor.dialogs.TileInstancePropertiesDialog

/*
* Tiled Map Editor, (c) 2004-2006
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* Adam Turk <aturk@biggeruniverse.com> Bjorn Lindeijer <bjorn@lindeijer.nl>
*/

package de.yaams.extensions.basemap.tiled.mapeditor.dialogs;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.Properties;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellEditor;

import de.yaams.extensions.basemap.tiled.core.MapLayer;
import de.yaams.extensions.basemap.tiled.core.Tile;
import de.yaams.extensions.basemap.tiled.core.TileLayer;
import de.yaams.extensions.basemap.tiled.mapeditor.MapEditor;
import de.yaams.extensions.basemap.tiled.mapeditor.Resources;
import de.yaams.extensions.basemap.tiled.mapeditor.selection.SelectionLayer;
import de.yaams.extensions.basemap.tiled.mapeditor.util.PropertiesTableModel;
import de.yaams.extensions.basemap.tiled.mapeditor.widget.VerticalStaticJPanel;
import de.yaams.maker.programm.YaFrame;

/**
* @version $Id$
*/
public class TileInstancePropertiesDialog extends JDialog implements TableModelListener {
  /**
   *
   */
  private static final long serialVersionUID = -8243150934312328656L;
  private JTable propertiesTable;
  private PropertiesTableModel tableModel = new PropertiesTableModel();

  private static final String DIALOG_TITLE = "Tile Properties"; // todo:
                                  // Resource
                                  // this
  private static final String APPLY_BUTTON = Resources.getString("general.button.apply");
  private static final String APPLY_TOOLTIP = "Apply properties to selected tiles"; // todo:
                                            // Resource
                                            // this
  private static final String DELETE_BUTTON = Resources.getString("general.button.delete");

  private final MapEditor editor;
  /** Holds all currently selected Properties. */
  private final LinkedList<Point> propertiesCoordinates = new LinkedList<Point>();
  private final Properties mergedProperties = new Properties();

  public TileInstancePropertiesDialog(MapEditor editor) {
    super(YaFrame.get(), DIALOG_TITLE, false);
    this.editor = editor;

    tableModel.addTableModelListener(this);

    init();
    pack();
    setLocationRelativeTo(getOwner());
  }

  private Properties getPropertiesAt(Point p) {
    MapLayer ml = editor.getCurrentLayer();
    if (!(ml instanceof TileLayer)) {
      return null;
    }

    return ((TileLayer) ml).getTileInstancePropertiesAt(p.x, p.y);
  }

  private void setPropertiesAt(Point point, Properties properties) {
    MapLayer ml = editor.getCurrentLayer();
    if (!(ml instanceof TileLayer)) {
      return;
    }

    ((TileLayer) ml).setTileInstancePropertiesAt(point.x, point.y, properties);
  }

  private void init() {
    propertiesTable = new JTable(tableModel);
    JScrollPane propScrollPane = new JScrollPane(propertiesTable);
    propScrollPane.setPreferredSize(new Dimension(200, 150));

    JButton applyButton = new JButton(APPLY_BUTTON);
    applyButton.setToolTipText(APPLY_TOOLTIP);
    JButton deleteButton = new JButton(Resources.getIcon("gnome-delete.png"));
    deleteButton.setToolTipText(DELETE_BUTTON);

    JPanel user = new VerticalStaticJPanel();
    user.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
    user.setLayout(new BoxLayout(user, BoxLayout.X_AXIS));
    user.add(Box.createGlue());
    user.add(Box.createRigidArea(new Dimension(5, 0)));
    user.add(deleteButton);

    JPanel buttons = new VerticalStaticJPanel();
    buttons.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
    buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS));
    buttons.add(Box.createGlue());
    buttons.add(applyButton);

    JPanel mainPanel = new JPanel();
    mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
    mainPanel.add(propScrollPane);
    mainPanel.add(user);
    mainPanel.add(buttons);

    getContentPane().add(mainPanel);
    getRootPane().setDefaultButton(applyButton);

    // create actionlisteners
    applyButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent actionEvent) {
        buildPropertiesAndApply();
      }
    });

    deleteButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent actionEvent) {
        deleteSelected();
      }
    });
  }

  public void setSelection(SelectionLayer selection) {
    // Start off fresh...
    // Properties mergedProperties = new Properties();
    mergedProperties.clear();
    propertiesCoordinates.clear();

    // Get all properties of all selected tiles...
    MapLayer ml = editor.getCurrentLayer();
    if (ml instanceof TileLayer) {
      TileLayer tl = (TileLayer) ml;
      Rectangle r = selection.getSelectedAreaBounds();
      int maxJ = (int) (r.getY() + r.getHeight());
      int maxI = (int) (r.getX() + r.getWidth());

      // todo: BL - Why are tiles checked on null? Surely whether a tile
      // todo: is null or not has nothing to do with whether you can place
      // todo: a property as a certain location?
      for (int j = (int) r.getY(); j < maxJ; j++) {
        for (int i = (int) r.getX(); i < maxI; i++) {
          Tile t = selection.getTileAt(i, j);
          if (t != null) {
            propertiesCoordinates.add(new Point(i, j));
          }
        }
      }

      if (!propertiesCoordinates.isEmpty()) {
        // Start with properties of first tile instance
        Point point = propertiesCoordinates.get(0);
        Properties p = tl.getTileInstancePropertiesAt(point.x, point.y);

        if (p != null) {
          mergedProperties.putAll(p);

          for (int i = 1; i < propertiesCoordinates.size(); i++) {
            // Merge the other properties...
            point = propertiesCoordinates.get(i);
            p = tl.getTileInstancePropertiesAt(point.x, point.y);

            if (p != null) {
              for (Enumeration<?> e = mergedProperties.keys(); e.hasMoreElements();) {
                // We only care for properties that are already
                // "known"...
                String key = (String) e.nextElement();
                String val = mergedProperties.getProperty(key);
                String mval = p.getProperty(key);

                if (mval == null) {
                  // Drop non-common properties
                  mergedProperties.remove(key);
                } else if (!mval.equals(val)) {
                  // Hide non-common values
                  mergedProperties.setProperty(key, "?");
                }
              }
            } else {
              mergedProperties.clear();
              break;
            }
          }
        }
      }
    }

    tableModel.setProperties(mergedProperties);
  }

  private void buildPropertiesAndApply() {
    // Make sure there is no active cell editor anymore
    TableCellEditor cellEditor = propertiesTable.getCellEditor();
    if (cellEditor != null) {
      cellEditor.stopCellEditing();
    }

    // Apply possibly changed properties.
    applyPropertiesToTiles();
  }

  private void deleteFromSelectedTiles(String key) {
    for (Point point : propertiesCoordinates) {
      Properties p = getPropertiesAt(point);
      if (p != null) {
        p.remove(key);
      }
    }
  }

  private void deleteSelected() {
    int total = propertiesTable.getSelectedRowCount();
    Object[] keys = new Object[total];
    int[] selRows = propertiesTable.getSelectedRows();

    for (int i = 0; i < total; i++) {
      keys[i] = propertiesTable.getValueAt(selRows[i], 0);
    }

    for (int i = 0; i < total; i++) {
      if (keys[i] != null) {
        tableModel.remove(keys[i]);
        deleteFromSelectedTiles((String) keys[i]);
      }
    }
  }

  private void applyPropertiesToTiles() {
    Properties properties = tableModel.getProperties();

    // First delete all Properties that were previously selected
    for (Point point : propertiesCoordinates) {
      Properties tp = getPropertiesAt(point);
      if (tp != null) {
        for (Enumeration<?> e = mergedProperties.keys(); e.hasMoreElements();) {

          String key = (String) e.nextElement();
          String val = (String) properties.get(key);

          if (!"?".equals(val)) {
            // Property was removed or has a valid new value
            tp.remove(key);
          }
        }
      }
    }

    // Now update all selected Properties with the
    // new data
    for (Point point : propertiesCoordinates) {
      Properties tp = getPropertiesAt(point);
      if (tp == null) {
        tp = new Properties();
        setPropertiesAt(point, tp);
      }

      for (Enumeration<?> e = properties.keys(); e.hasMoreElements();) {
        String key = (String) e.nextElement();
        String val = properties.getProperty(key);
        if (!"?".equals(val)) {
          tp.setProperty(key, val);
        }
      }
    }
  }

  @Override
  public void tableChanged(TableModelEvent e) {
    applyPropertiesToTiles();
  }
}
TOP

Related Classes of de.yaams.extensions.basemap.tiled.mapeditor.dialogs.TileInstancePropertiesDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.